<template>
  <div>
    <!-- 搜索条件 -->
    <el-card v-show="showQueryForm" class="form-card">
      <QueryForm ref="queryFormRef" :form-data="queryFormData" :items="queryFormItems" :model="queryFormData" :show-control="true" label-width="82px">

        <QueryFormItem label="下单时间">
          <el-date-picker v-model="pickerDate"
                          :shortcuts="pickerShortcuts"
                          class="card-header-extra-action"
                          clearable
                          end-placeholder="结束日期"
                          format="YYYY-MM-DD"
                          start-placeholder="开始日期"
                          type="daterange"
                          value-format="YYYY-MM-DD"/>
        </QueryFormItem>

        <template #control>
          <el-button icon="Search" type="info" @click="handleSearch">{{ $t('form.search') }}</el-button>
          <el-button icon="Refresh" @click="handleResetQueryForm">{{ $t('form.reset') }}</el-button>
        </template>
      </QueryForm>
    </el-card>

    <!-- 列表数据 -->
    <el-card class="content-card">
      <el-tabs v-model="tabActive" @tab-change="handleTabChange">
        <el-tab-pane v-for="item in tabHeaderList" :key="item.type" :label="`${item.name}(${item.count})`" :name="item.type"></el-tab-pane>
      </el-tabs>

      <!-- 工具栏 -->
      <table-toolbar v-model:columns="columns"
                     v-model:show-query-form="showQueryForm"
                     v-model:size="size"
                     v-model:stripe="stripe"
                     @refresh="handleSearch">
        <!-- 操作区域 -->
        <template v-if="tabActive === 0">
          <el-button v-permission="'goods:order:export'" icon="download" plain type="warning" @click="handleDownloadExport">导出订单数据</el-button>
          <el-button v-permission="'goods:order:export'" icon="upload-filled" plain type="warning" @click="showOrderDeliveryImportForm">导入物流数据</el-button>
          <el-button v-permission="'goods:order:export'" icon="download" plain type="warning" @click="showOSalesDownloadForm">销售数据导出</el-button>
        </template>
      </table-toolbar>

      <!-- 列表记录 -->
      <div class="table-wrapper">
        <!-- 列表数据 -->
        <el-table ref="tableRef"
                  v-loading="loading"
                  :data="tableData"
                  :size="size"
                  :stripe="stripe"
                  row-key="id"
                  show-overflow-tooltip
                  @select="handleSelectChange"
                  @select-all="handleSelectAll"
                  @sort-change="handleSortChange">
          <template #empty>
            <el-empty class="table-empty" description="暂无数据"/>
          </template>

          <table-column :columns="columns">
            <template #item="scope">
              <el-popover :width="420" popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;" trigger="click">
                <template #reference>
                  <div v-if="scope.row.item_list.length > 0" class="sku-info-box">
                    <div class="sku-info-left">
                      <el-image :preview-src-list="[scope.row.item_list[0].goods_cover_url]" :preview-teleported="true" :src="scope.row.item_list[0].goods_cover_url"/>
                    </div>
                    <div class="sku-info-right">
                      <div class="sku-name">{{ scope.row.item_list[0].goods_name }}</div>
                    </div>
                  </div>
                </template>
                <template #default>
                  <div v-for="item in scope.row.item_list" :key="item.id" class="sku-info-popover">
                    <div class="sku-info-box">
                      <div class="sku-info-left">
                        <el-image :src="item.goods_cover_url"/>
                      </div>
                      <div class="sku-info-right">
                        <div class="sku-name">{{ item.goods_name }}</div>
                      </div>
                    </div>
                    <div class="sku-info-content">
                      <div class="name">编号：{{ item.goods_id }}</div>
                      <div class="name">规格：{{ item.spec_key_name || '-' }}</div>
                      <div class="price">
                        <span class="flex_1_5">售价：<span class="money-sum">￥{{ numeral(item.price).format('0.00') }}</span></span>
                        <span class="flex_1_5">供货：<span class="money-sum">￥{{ numeral(item.price_cost).format('0.00') }}</span></span>
                        <span class="flex1">数量：<span>x{{ item.quantity }}</span></span>
                      </div>
                    </div>
                  </div>
                </template>
              </el-popover>
            </template>

            <template #shop_id="scope">
              <span>{{ scope.row.shop_name || '' }}</span>
            </template>

            <template #user_id="scope">
              <span>{{ scope.row.account }}</span>
              /
              <UserInfoLink :user-id="scope.row.user_id"/>
            </template>

            <template #status="scope">
              <DictTag v-model="scope.row.status" :circle="false" dict-type="shop_order_status"/>
            </template>

            <template #payment_status="scope">
              <DictTag v-model="scope.row.payment_status" :circle="false" dict-type="shop_order_payment_status"/>
            </template>

            <template #payment_type="scope">
              <DictTag v-if="scope.row.payment_type > 0" v-model="scope.row.payment_type" :circle="false" dict-type="shop_order_payment_type"/>
              <span v-else>-</span>
            </template>

            <template #operations="scope">
              <!-- 查看订单信息 -->
              <el-button v-permission="'shop:order:info'" link type="info" @click="handleShowOrderInfo(scope.row.id)">详情</el-button>
              <!-- 有退款权限 且 订单已支付 且 未完成  -->
              <template v-if="hasPermission('shop:order:refund') && scope.row.payment_status === 2">
                <el-button v-if="scope.row.status === 20 || scope.row.status === 30" link type="danger" @click="handleOrderRefund(scope.row)">退款</el-button>
              </template>
              <!-- 支付状态 0:未支付 1:支付中 2:已支付 3:已退款 4:部分退款 -->
              <!-- 订单状态 10:待付款 20:发货中 30:待收货 100:已完成 110:已取消 120:付款失败 200:已退款 -->
              <div v-if="scope.row.payment_status === 2 && hasPermission('shop:order:delivery') " style="margin-top: 5px">
                <!-- 订单发货 只能 20:发货中 30:待收货 -->
                <el-button v-if="[20,30].includes(scope.row.status)"
                           :type="scope.row.status === 30 ? 'success' : scope.row.status === 20 ? 'primary' : 'info'"
                           link
                           @click="showOrderDeliveryForm(scope.row)">
                  {{ scope.row.status === 30 ? '修改发货' : scope.row.status === 20 ? '订单发货' : '发货信息' }}
                </el-button>
              </div>
            </template>
          </table-column>
        </el-table>

        <!-- 分页操作 -->
        <el-pagination v-if="totalCount > 0"
                       :current-page="pageQuery.pageNum"
                       :page-size="pageQuery.pageSize"
                       :page-sizes="pageSizes"
                       :total="totalCount"
                       background
                       class="table-pagination"
                       layout="total, sizes, prev, pager, next"
                       @size-change="handleSizeChange"
                       @current-change="handleCurrentChange"/>
      </div>
    </el-card>

    <!-- 弹窗操作 -->
    <OrderInfoDrawer ref="orderInfoRef"/>
    <!-- 发货操作 -->
    <OrderDeliveryForm ref="orderDeliveryRef" @refresh="handleSearch"/>
    <!-- 物流导入 -->
    <OrderDeliveryImportForm ref="orderDeliveryImportRef" @refresh="handleSearch"/>
    <!-- 销量导出 -->
    <SalesDownloadForm ref="salesDownloadRef"/>
  </div>
</template>

<script lang="tsx" setup>
import { computed, h, onBeforeMount, reactive, ref } from 'vue';
import { QueryForm, QueryFormItem } from '@/components/query-form';
import useLoading from '@/hooks/use-loading';
import TableColumn, { TableColumnData } from '@/components/table-column/index.vue';
import TableToolbar from '@/components/table-toolbar/index.vue';
import useTableSelection from '@/hooks/use-table-selection';
import { ElLoading, ElMessage, ElMessageBox, ElNotification, TableInstance, TabsPaneContext } from 'element-plus';
import useTable from '@/hooks/use-table.ts';
import { hasPermission } from '@/utils/permission.ts';
import { computedOperateWidth, downloadFile, pickerShortcuts, toDecimal } from '@/utils';
import { QueryFormItemRule } from '@/components/query-form/constants.ts';
import { goodsOrderList, orderRefund, orderTabHeader, TabHeaderData } from '@/api/api-shop.ts';
import { DictTag } from '@/components/dict-tag';
import numeral from 'numeral';
import OrderInfoDrawer from './order-info-drawer.vue';
import OrderDeliveryForm from './components/order-delivery-form.vue';
import OrderDeliveryImportForm from './components/order-delivery-import-form.vue';
import SalesDownloadForm from './components/sales-download-form.vue';
import { UserInfoLink } from '@/components/user-info-link';
import { download } from '@/utils/axios/axios-service.ts';

defineOptions({name: 'goods-order-list'});

// 查询
const queryFormData = reactive({
  id: undefined,
  order_no: undefined,
  account: undefined,
  user_id: undefined,
  goods_id: undefined,
  goods_name: undefined,
  shop_name: undefined,
  status: undefined,
  payment_status: undefined,
  tab_type: undefined,
  // 时间范围 格式 2023-01-01~2023-01-31
  date: undefined,
});
const queryFormRef = ref<InstanceType<typeof QueryForm>>();
const queryFormItems = ref<QueryFormItemRule[]>([
  {type: 'input', prop: 'id', label: '订单编号', placeholder: '请输入订单编号', clearable: true},
  {type: 'input', prop: 'order_no', label: '订单号', placeholder: '请输入订单号', clearable: true,},
  {type: 'input', prop: 'account', label: '用户账号', placeholder: '请输入用户账号', clearable: true,},
  {type: 'input', prop: 'user_id', label: '用户编号', placeholder: '请输入用户编号', clearable: true,},
  {type: 'input', prop: 'goods_id', label: '商品编号', placeholder: '请输入商品编号', clearable: true,},
  {type: 'input', prop: 'goods_name', label: '商品名称', placeholder: '请输入商品名称', clearable: true,},
  {type: 'input', prop: 'shop_name', label: '店铺名称', placeholder: '请输入店铺名称', clearable: true,},
  {type: 'dict-select', prop: 'status', label: '订单状态', placeholder: '请选择订单状态', dictType: 'shop_order_status', clearable: true,},
  {type: 'dict-select', prop: 'payment_status', label: '支付状态', placeholder: '请选择支付状态', dictType: 'shop_order_payment_status', clearable: true,},
]);

// 列表数据
const tableRef = ref<TableInstance>();
const tableData = ref<any[]>([]);
const totalCount = ref(0);
const pickerDate = ref([]);

// 操作区域宽度计算
const operateWidth = computed(() => {
  let count = 0
  if (hasPermission('shop:order:info') || hasPermission('shop:order:delivery') || hasPermission('shop:order:refund')) count += 2
  return computedOperateWidth(count);
});

// 列设置
const columns = ref<TableColumnData[]>([
  {prop: 'id', label: '编号', width: 105, align: 'center', sortable: 'custom'},
  {prop: 'order_no', label: '订单号', minWidth: 200, align: 'right', headerAlign: 'center', sortable: 'custom'},
  {prop: 'shop_id', label: '店铺名称', minWidth: 180, align: 'center', headerAlign: 'center', sortable: 'custom'},
  {prop: 'item', label: '商品信息', minWidth: 300, align: 'left', headerAlign: 'center', showOverflowTooltip: false},
  {prop: 'user_id', label: '下单用户', minWidth: 160, align: 'center', sortable: 'custom'},
  {prop: 'total_price', label: '订单金额', minWidth: 120, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 2) : '-'}</span>},
  {prop: 'total_price_integral', label: '花朵金额', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 2) : '-'}</span>},
  {prop: 'total_price_cash', label: '现金支付', minWidth: 120, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 2) : '-'}</span>},
  {prop: 'coupon_payed', label: '消费券抵扣', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 2) : '-'}</span>},
  {prop: 'consume_gold_payed', label: '消费金抵扣', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 2) : '-'}</span>},
  {prop: 'settle_amount', label: '结算金额', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 4) : '-'}</span>},
  {prop: 'settle_amount_cash', label: '现金结算', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 4) : '-'}</span>},
  {prop: 'settle_amount_balance', label: '余额结算', minWidth: 130, align: 'right', headerAlign: 'center', sortable: 'custom', render: (scope, val) => <span>{val ? toDecimal(val, 4) : '-'}</span>},
  {prop: 'status', label: '订单状态', minWidth: 120, align: 'center', sortable: 'custom'},
  {prop: 'payment_status', label: '支付状态', minWidth: 120, align: 'center', sortable: 'custom'},
  {prop: 'payment_type', label: '支付方式', minWidth: 120, align: 'center', sortable: 'custom'},
  {prop: 'create_time', label: '下单时间', width: 180, align: 'center', sortable: 'custom', render: (scope, val) => <span>{val || '-'}</span>},
  {prop: 'payment_success_time', label: '支付时间', width: 180, align: 'center', sortable: 'custom', render: (scope, val) => <span>{val || '-'}</span>},
  {prop: 'complete_time', label: '完成时间', width: 180, align: 'center', sortable: 'custom', render: (scope, val) => <span>{val || '-'}</span>},
  {prop: 'cancel_time', label: '取消时间', width: 180, align: 'center', sortable: 'custom', render: (scope, val) => <span>{val || '-'}</span>},
  {prop: 'update_time', label: '更新时间', width: 180, align: 'center', sortable: 'custom', render: (scope, val) => <span>{val || '-'}</span>},
]);

onBeforeMount(() => {
  if (operateWidth.value > 0) {
    columns.value.push({prop: 'operations', label: '操作', fixed: 'right', width: operateWidth.value, align: 'left', headerAlign: 'center'},)
  }
  initTabHeaderData();
});

const [loading, setLoading] = useLoading(false);
const {tableMethods, tableState} = useTable(() => fetchDataList(), queryFormRef, true, true);
const {size, stripe, showQueryForm, pageQuery, pageSizes} = tableState;
const {handleSizeChange, handleCurrentChange, handleSortChange, handleResetForm} = tableMethods;
const {handleSelectChange, handleSelectAll, multipleSelection, clearSelection} = useTableSelection(tableData, tableRef);

// 数据查询
const fetchDataList = async () => {
  setLoading(true);
  try {
    // 处理其他参数条件
    handleOtherQueryParams();
    // 查询数据
    const {data} = await goodsOrderList({
      page_num: pageQuery.pageNum,
      page_size: pageQuery.pageSize,
      order_mode: pageQuery.orderMode,
      order_column: pageQuery.orderColumn,
      ...queryFormData,
    });
    // 结果转换
    tableData.value = data.list;
    totalCount.value = data.pages.total_count;
  } catch (err) {
  } finally {
    setLoading(false);
  }
};

// 刷新数据
const handleSearch = () => {
  initTabHeaderData();
  fetchDataList();
};

// 重置查询条件
const handleResetQueryForm = () => {
  pickerDate.value = [];
  tabActive.value = 0;
  clearSelection();
  handleResetForm();
};

/** 添加/修改操作 */
const orderInfoRef = ref();
const handleShowOrderInfo = (id: number) => {
  orderInfoRef.value?.open(id);
};

const orderDeliveryRef = ref();
const showOrderDeliveryForm = (row: any) => {
  orderDeliveryRef.value?.open(row);
};

const orderDeliveryImportRef = ref();
const showOrderDeliveryImportForm = (row: any) => {
  orderDeliveryImportRef.value?.open(row);
};

const salesDownloadRef = ref();
const showOSalesDownloadForm = () => {
  salesDownloadRef.value?.open();
};

/** Tab数据 */
const tabActive = ref(0);
const tabHeaderList = ref<TabHeaderData[]>([]);
const initTabHeaderData = async () => {
  handleOtherQueryParams();
  const {data} = await orderTabHeader(queryFormData);
  tabHeaderList.value = data;
};

/** Tab 改变时触发 */
const handleTabChange = (tab: TabsPaneContext, event: Event) => {
  fetchDataList();
};

// 处理其他查询条件
const handleOtherQueryParams = () => {
  // 时间范围参数
  // @ts-ignore
  queryFormData.date = pickerDate.value && pickerDate.value.length == 2 ? pickerDate.value[0] + '~' + pickerDate.value[1] : undefined

  // @ts-ignore
  queryFormData.tab_type = tabActive.value
  if (tabActive.value) {
    queryFormData.status = undefined
  }
}

/** 订单退款 */
const handleOrderRefund = (row: any) => {
  ElMessageBox.prompt(h('p', null, ['是否确认将订单 ', h('span', {style: 'font-weight: bold'}, row.order_no), ' 进行退款操作吗？',]), {
    title: '提示',
    type: 'warning',
    showCancelButton: true,
    confirmButtonText: '通过',
    cancelButtonText: '取消',
    inputPlaceholder: '请输入操作原因',
  }).then(({value}) => {
    if (value == null || value.length <= 0) {
      ElMessage.error('请输入操作原因')
      return
    }

    const loading = ElLoading.service({
      lock: true,
      text: '正在提交中...',
      background: 'rgba(0, 0, 0, 0.2)'
    })
    let params = {
      id: row.id,
      status: 1,
      reason: value
    }
    // 提交数据
    orderRefund(params).then(response => {
      // 提示信息
      ElNotification({title: '成功', message: '操作完成', type: 'success', duration: 2000})
      // 刷新列表数据
      handleSearch();
    }).finally(() => loading.close())
  });
};

/** 导出数据 */
const handleDownloadExport = () => {
  ElMessageBox.confirm(h('p', null, ['是否确认进行 ', h('span', {style: 'font-weight: bold;'}, '导出订单数据'), `操作吗？ 注：导出数据按查询条件进行筛选导出`,]), '提示', {
    type: 'warning',
    closeOnClickModal: false,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  }).then(() => {
    const loading = ElLoading.service({
      lock: true,
      text: '正在导出数据中...',
      background: 'rgba(0, 0, 0, 0.2)'
    })
    // 时间范围参数
    // @ts-ignore
    queryFormData.date = pickerDate.value && pickerDate.value.length == 2 ? pickerDate.value[0] + '~' + pickerDate.value[1] : undefined;
    // 调用函数
    download('/shop/order/download_excel', queryFormData).then(result => {
      downloadFile(result, `订单数据`, 'xlsx')
    }).finally(() => loading.close())
  }).catch(() => {

  });
};

</script>

<style lang="scss" scoped>
.sku-info-box {
  width: 100%;
  cursor: pointer;
  display: flex;

  .sku-info-left {
    float: left;

    :deep() {
      .el-image {
        width: 32px;
        height: 32px;
      }

      .el-image__error {
        font-size: 9px;
      }
    }
  }

  .sku-info-right {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-left: 6px;

    .sku-name {
      font-size: 12px;
      line-height: 14px;
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
    }
  }
}

.sku-info-popover {
  display: flex;
  gap: 16px;
  flex-direction: column;
}

.sku-info-content {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  font-size: 13px;
  margin: 0 5px;

  .name {
    height: 1.3rem;
    line-height: 1.2rem;
    color: var(--el-color-info);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .price {
    height: 1.3rem;
    line-height: 1.2rem;
    color: var(--el-color-info);
    display: flex;
    -webkit-box-pack: justify;
    justify-content: space-between;
  }

  .money-sum {
    color: #AA62FF;
  }
}

</style>
